using System;
using System.IO;

using Atomic.Libraries;
using Atomic.Libraries.Compression;

namespace Atomic.Vasp
{
	[Serializable]
	public class BaseVaspResult
	{
		private CompressedData chg, chgcar, contcar, doscar, dynmat, eigenval, ibzkpt, incar, kpoints, oszicar, outcar, poscar, wavecar, vasprun;

		public BaseVaspResult(DirectoryInfo directory)
		{
			ReadFile(directory, "CHG", false, out chg);
			ReadFile(directory, "CHGCAR", false, out chgcar);
			ReadFile(directory, "CONTCAR", true, out contcar);
			ReadFile(directory, "DOSCAR", false, out doscar);
			ReadFile(directory, "DYNMAT", false, out dynmat);
			ReadFile(directory, "EIGENVAL", false, out eigenval);
			ReadFile(directory, "IBZKPT", false, out ibzkpt);
			ReadFile(directory, "INCAR", false, out incar);
			ReadFile(directory, "KPOINTS", false, out kpoints);
			ReadFile(directory, "OSZICAR", true, out oszicar);
			ReadFile(directory, "OUTCAR", true, out outcar);
			ReadFile(directory, "POSCAR", true, out poscar);
			ReadFile(directory, "WAVECAR", false, out wavecar);
			ReadFile(directory, "vasprun.xml", true, out vasprun);
		}
		
		private static void ReadFile(DirectoryInfo directory, string fileName, bool required, out CompressedData data)
		{
			if (directory.AddFile(fileName).AddFileExtension(".ignore").Exists && !required)
			{
				// Ignore this file.
				data = null;
				return;
			}

			if (directory.AddFile(fileName).Exists && directory.AddFile(fileName).Length > 0)
			{
				data = CompressedData.Read(directory.AddFile(fileName));
				return;
			}

			if (directory.AddFile(fileName).AddFileExtension(".bz2").Exists && directory.AddFile(fileName).AddFileExtension(".bz2").Length > 0)
			{
				data = CompressedData.ReadCompressed(directory.AddFile(fileName).AddFileExtension(".bz2"));
				return;
			}

			if (required)
			{
				throw new FileNotFoundException("Couldn't find VASP output file.", directory.AddFile(fileName).FullName);
			}

			data = null;
		}

		public void Compress()
		{
			foreach (CompressedData data in new CompressedData[] { chg, chgcar, contcar, doscar, dynmat, eigenval, ibzkpt, incar, kpoints, oszicar, outcar, poscar, wavecar, vasprun })
			{
				if (data != null)
				{
					data.Compress();
				}
			}
		}
		
		public CompressedData Chg
		{
			get
			{
				return chg;
			}
		}

		public CompressedData Chgcar
		{
			get
			{
				return chgcar;
			}
		}

		public CompressedData Contcar
		{
			get
			{
				return contcar;
			}
		}

		public CompressedData Doscar
		{
			get
			{
				return doscar;
			}
		}

		public CompressedData Dynmat
		{
			get
			{
				return dynmat;
			}
		}
		
		public CompressedData Eigenval
		{
			get
			{
				return eigenval;
			}
		}
		
		public CompressedData Ibzkpt
		{
			get
			{
				return ibzkpt;
			}
		}
		
		public CompressedData Incar
		{
			get
			{
				return incar;
			}
		}
		
		public CompressedData Kpoints
		{
			get
			{
				return kpoints;
			}
		}
		
		public CompressedData Oszicar
		{
			get
			{
				return oszicar;
			}
		}
		
		public CompressedData Outcar
		{
			get
			{
				return outcar;
			}
		}
		
		public CompressedData Poscar
		{
			get
			{
				return poscar;
			}
		}
			
		public CompressedData Wavecar
		{
			get
			{
				return wavecar;
			}
		}

		public CompressedData Vasprun
		{
			get
			{
				return vasprun;
			}
		}
	}
}
